﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Data;
using StyleMVVM.DependencyInjection;
using StyleMVVM.UnitTests.TestClasses.ValidationObjects.Automobile;
using StyleMVVM.Validation;
using StyleMVVM.Validation.Impl;
using StyleMVVM.Validation.Impl.Fluent;
#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Windows.ApplicationModel.Resources;

#else
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endif

namespace StyleMVVM.UnitTests.Validation.Fluent
{
	[TestClass]
	public class StringPropertyModifierTests : BaseTestClass
	{
		[TestMethod]
		public void StartsWithOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).StartsWith("Blah");

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "Blah";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void EndsWithOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).EndsWith("Blah");

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "Blah";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void IndexOfOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).IndexOf("Blah").GreaterThanOrEqualTo.Value(5);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "HelloBlah";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void LastIndexOfOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).LastIndexOf("Blah").GreaterThanOrEqualTo.Value(4);

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "BlahBlah";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void ToLowerOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).ToLower().EqualTo.Value("blah");

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "BlaH";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}

		[TestMethod]
		public void ToUpperOperatorRule()
		{
			ResourceLoader fluentResources = new ResourceLoader("StyleMVVM.CSharp/FluentResources");
			FluentRule<Car> wheelsRule = new FluentRule<Car>(Container.Locate<IReflectionService>(), "WheelRule");

			wheelsRule.StringProperty(x => x.LicensePlate).ToUpper().EqualTo.Value("BLAH");

			wheelsRule.Compile(fluentResources);

			Car newCar = new Car();

			RuleExecutionContext context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Invalid, context.State);

			newCar.LicensePlate = "blah";

			context = new RuleExecutionContext(newCar);

			wheelsRule.Validate(context);

			Assert.AreEqual(ValidationState.Valid, context.State);
		}
	}
}